package com.yanqu.road.dataHelper.action.excel;

import com.yanqu.road.dataHelper.gameServer.GameServer;
import com.yanqu.road.dataHelper.ipdb.City;
import com.yanqu.road.dataHelper.ipdb.CityInfo;
import com.yanqu.road.dataHelper.ipdb.IPFormatException;
import com.yanqu.road.dataHelper.ipdb.InvalidDatabaseException;
import com.yanqu.road.dataHelper.repair.BaseRepair;
import com.yanqu.road.entity.servercenter.IpInfo;
import com.yanqu.road.utils.redis.JedisHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class AddIpInfoLogin extends BaseRepair {
    public AddIpInfoLogin(GameServer gameServer) {
        super(gameServer);
    }

    @Override
    public void repair(long param1, String param2) {

    }

    public void go(City city, JedisHelper jedisUtils) {
        Set<String> chinaLocationSet = new HashSet<>();
        chinaLocationSet.add("湖南");
        chinaLocationSet.add("湖北");
        chinaLocationSet.add("河南");
        chinaLocationSet.add("山东");
        chinaLocationSet.add("江西");
        chinaLocationSet.add("安徽");
        chinaLocationSet.add("浙江");
        chinaLocationSet.add("江苏");
        chinaLocationSet.add("黑龙江");
        chinaLocationSet.add("吉林");
        chinaLocationSet.add("辽宁");
        chinaLocationSet.add("山西");
        chinaLocationSet.add("河北");
        chinaLocationSet.add("福建");
        chinaLocationSet.add("西藏");
        chinaLocationSet.add("宁夏");
        chinaLocationSet.add("广西");
        chinaLocationSet.add("内蒙古");
        chinaLocationSet.add("台湾");
        chinaLocationSet.add("青海");
        chinaLocationSet.add("甘肃");
        chinaLocationSet.add("陕西");
        chinaLocationSet.add("云南");
        chinaLocationSet.add("四川");
        chinaLocationSet.add("贵州");
        chinaLocationSet.add("海南");
        chinaLocationSet.add("广东");
        chinaLocationSet.add("澳门");
        chinaLocationSet.add("香港");
        chinaLocationSet.add("重庆");
        chinaLocationSet.add("上海");
        chinaLocationSet.add("天津");
        chinaLocationSet.add("北京");
        chinaLocationSet.add("新疆");

        //获取信息为未知的玩家
        List<Long> userList = unknownIpUserList();
        int addNum = 0;
        // 获取玩家最近一次登录的ip
        for (Long userId : userList) {
            String ip = getLastLoginIp(userId);
            if (ip != null) {
                try {
                    CityInfo cityInfo = city.findCity(ip, "CN");
                    if (cityInfo != null) {
                        String countryName = cityInfo.getCountryName();
                        if ("中国".equals(countryName)) {
                            String regionName = cityInfo.getRegionName();
                            boolean valid = false;
                            for (String name : chinaLocationSet) {
                                if (regionName.contains(name)) {
                                    valid = true;
                                    break;
                                }
                            }
                            IpInfo ipInfo = new IpInfo();
                            ipInfo.setCountry(countryName);
                            ipInfo.setProvince(regionName);
                            if (!valid) {
                                getLogger().info("no valid province: {},ip: {}", regionName, ip);
                                continue;
                            }
                            addNum++;
                            String subIpStr = ip.substring(0, ip.lastIndexOf(".") + 1);
                            jedisUtils.addMapValueByKey("SERVERIPTOCITY", subIpStr, ipInfo);
                        } else {
                            String regionName = cityInfo.getRegionName();

                            IpInfo ipInfo = new IpInfo();
                            ipInfo.setCountry(countryName);
                            ipInfo.setProvince(regionName);
                            addNum++;
                            String subIpStr = ip.substring(0, ip.lastIndexOf(".") + 1);
                            jedisUtils.addMapValueByKey("SERVERIPTOCITY", subIpStr, ipInfo);
                        }
                    }else {
                        getLogger().info("city is null. ip: {}", ip);
                    }
                } catch (IPFormatException | InvalidDatabaseException e) {
                   getLogger().error("IPFormatException ",e);
                }
            }else {
                getLogger().info("ip is null, {}", userId);
            }
        }
        if (userList.size() != addNum) {
            getLogger().info("userSize: {}, addNum: {}", userList.size(), addNum);
        }
    }

    public List<Long> unknownIpUserList() {
        ResultSet rs = null;
        CallableStatement call = null;
        List<Long> userList = new ArrayList<>();
        String sql = "select userId from t_u_user where ipLocation = ?";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            call.setString(1, "未知");
            rs = call.executeQuery();
            while (rs.next()) {
                long userId = rs.getLong("userId");
                userList.add(userId);
            }
        } catch (Exception e) {
        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return userList;
    }

    public String getLastLoginIp(long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select ip from t_l_login where userId = ? and type = 0 ORDER BY time desc limit 10;";
        try {
            call = getGameServer().getLogConnection().prepareCall(sql);
            call.setLong(1, userId);
            rs = call.executeQuery();
            while (rs.next()) {
                String ip = rs.getString("ip");
                if (!StringUtils.isNullOrEmpty(ip)) {
                    return ip;
                }
            }
        } catch (Exception e) {

        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return null;
    }
}
